"""
===================================================
    FILENAME: main.py
    东川路集群智能运输大队
    指导老师：张庆昊，邬明宇，卢俊国
    小组成员：景序，谭睿佳，于沛龙
===================================================
"""

from rflysim import RflysimEnvConfig
from rflysim.client import VehicleClient
from rflysim.config import AreaInfo, Position
import time
import json
import os
import random
import objects
import algorithm

def generate_json(client: VehicleClient):
    """
    生成json文件
    """
    
    # 定义要保存的目标路径
    target_directory = r"E:\temp"
    target_file_path = os.path.join(target_directory, "config.json")

    areaData = client.get_areas()

    data = {"redis_api": 16001, "frontend_api_port": 18001, "proposal_id": 102}

    data["max_speed"] = [30, 30, 15, 15, 10] # 手动修改

    pkg_weight = set()
    for obj in areaData:
        if obj.sim_type in [12, 14, 15]:
            for pkg in obj.packages:
                pkg_weight.add(pkg.weight)
    pkg_weight = sorted(list(pkg_weight))
    data["package_weight"] = pkg_weight

    temp = client.get_vehicle_capacity()
    data["vehicle_capacity"] = sorted([int(i.cap) for i in temp])

    pkg_map = {}
    light_delivery = []
    light_pkg = []
    medium_delivery = []
    medium_pkg = []
    heavy_delivery = []
    heavy_pkg = []
    for obj in areaData:
        if obj.sim_type == 12:
            for pkg in obj.packages:
                light_pkg.append(pkg.id)
        elif obj.sim_type == 14:
            for pkg in obj.packages:
                medium_pkg.append(pkg.id)
        elif obj.sim_type == 15:
            for pkg in obj.packages:
                heavy_pkg.append(pkg.id)

        if obj.sim_type == 22:
            light_delivery.append(obj.id)
        elif obj.sim_type == 24:
            medium_delivery.append(obj.id)
        elif obj.sim_type == 25:
            heavy_delivery.append(obj.id)

    for id in light_pkg:
        pkg_map[str(id)] = random.choice(light_delivery)
    for id in medium_pkg:
        pkg_map[str(id)] = random.choice(medium_delivery)
    for id in heavy_pkg:
        pkg_map[str(id)] = random.choice(heavy_delivery)

    data["pkg_map"] = pkg_map

    # 检查目标目录是否存在，如果不存在则创建
    if not os.path.exists(target_directory):
        os.makedirs(target_directory)
        print(f"目录 {target_directory} 不存在，已自动创建")
    
    # 将配置数据写入JSON文件
    with open(target_file_path, 'w', encoding='utf-8') as json_file:
        json.dump(data, json_file, ensure_ascii=False, indent=4)
    
    print(f"配置文件已成功生成并保存到: {target_file_path}")
    print("文件内容预览:")
    print(json.dumps(data, ensure_ascii=False, indent=2))
    
    return True

globalTimeStart = time.time()

client = VehicleClient(id=102, config=RflysimEnvConfig("127.0.0.1", 16001, 18001))
client.enable_rflysim()

client.stop()
client.start()
generate_json(client)
time.sleep(10)
client.stop()

# read vehicle max speed and package destination
# with open('config.json', 'r') as f:
#     tempData = json.load(f)
with open('E:\\temp\\config.json', 'r') as f:
    tempData = json.load(f)
maxSpeedList = tempData["max_speed"]
maxSpeedList.sort(reverse = True)
capacityListJson = tempData["vehicle_capacity"]
capacityListJson.sort()
packageDest = tempData["pkg_map"]
redis_api = tempData["redis_api"]
frontend_api_port = tempData["frontend_api_port"]
proposal_id = tempData["proposal_id"]

#initialize and start the client
client = VehicleClient(id=proposal_id, config=RflysimEnvConfig("127.0.0.1", redis_api, frontend_api_port))
client.enable_rflysim()

client.stop()
client.start()
time.sleep(0.3)

#initialize objects and vehicles in map
vehicles = []
pickAreas = []
deliveryAreas = []
barriers = []

areaData = client.get_areas()
for objs in areaData:
    if objs.sim_type in [12, 14, 15]:
        tempVertices = objs.LONLAT
        tempShape = objects.Shape(nZoneType=objs.nZoneType, vertices=tempVertices)
        tempPkgIDList = [objs.packages[i] for i in range(len(objs.packages))]
        tempPackages = [objects.Package(pkg, packageDest[str(pkg.id)]) for pkg in tempPkgIDList]
        pickAreas.append(objects.Pick(objs.id, tempShape, objs.sim_type, tempPackages))
    elif objs.sim_type in [22, 24, 25]:
        tempVertices = objs.LONLAT
        tempShape = objects.Shape(nZoneType=objs.nZoneType, vertices=tempVertices)
        deliveryAreas.append(objects.Delivery(objs.id, tempShape, objs.sim_type))
    elif objs.sim_type == 23:
        tempVertices = objs.LONLAT
        #tempRadius = objs.radius
        tempRadius = None
        tempShape = objects.Shape(objs.nZoneType, tempVertices, tempRadius)
        barriers.append(algorithm.ExtendedBarrier(objects.Barrier(objs.id, tempShape)))

tempVehicleDatas = client.get_vehicle_pos()
tempVehicleCap = client.get_vehicle_capacity()
capacityList = []
for capInfo in tempVehicleCap:
    capacityList.append(capInfo.cap)
capacityList.sort()

for id, pos in tempVehicleDatas.items():
    for info in tempVehicleCap:
        if info.id == id:
            if info.cap in [capacityList[0], capacityList[1]]:
                velcoity = maxSpeedList[0]
                vType = 0
            elif info.cap in [capacityList[2], capacityList[3]]:
                velcoity = maxSpeedList[1]
                vType = 1
            else:
                velcoity = maxSpeedList[2]
                vType = 2
            vehicles.append(objects.Vehicle(id, info.cap, velcoity, vType, Position(pos.x, pos.y)))

#main logic
algorithmTimeStart = time.time()

algorithm.vehicleRun(vehicles, pickAreas, deliveryAreas, barriers, client)

algorithmTimeEnd = time.time()
globalTimeEnd = time.time()

print("Global time cost:", globalTimeEnd - globalTimeStart)
print("Algorithm time cost:", algorithmTimeEnd - algorithmTimeStart)
client.stop()